package com.hp.bon.sgw.service;

import com.google.gson.Gson;
import com.hp.bon.sgw.Constants.NodeStatus;
import com.hp.bon.sgw.Constants.NodeType;
import com.hp.bon.sgw.bean.CapabilityCtrlBean;
import com.hp.bon.sgw.domain.*;
import com.hp.bon.sgw.util.dcc.DccAvpHelper;
import org.apache.commons.configuration.Configuration;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 负责将Table形式的参数加载并拼成配置文件兼容的字符串格式的参数
 *
 * @author wuzhih
 *
 */
public class TableBaseConfLoader {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(TableBaseConfLoader.class);
	private HibernateTemplate hibernateTemplate;


//	private SgwViewDao sgwViewDao;
//
//	@Autowired
//	public void setSgwViewDao(SgwViewDao sgwViewDao) {
//		this.sgwViewDao = sgwViewDao;
//	}

	@SuppressWarnings("unchecked")
	@Transactional(readOnly = false, timeout = 10)
	public void loadtoConfig(ConfigService confSrv) {
		Configuration curConfig = confSrv.getCurConfig();
		// 加载AVP XML映射表
		loadConvMapInfoTable(curConfig);

		List<SGWChannel> sgwChannels = this.hibernateTemplate.loadAll(SGWChannel.class);

		List<Node> nodes = this.hibernateTemplate.loadAll(Node.class);
		List<SGWCapabilityProvided> capaProvided = this.hibernateTemplate.loadAll(SGWCapabilityProvided.class);
		List<OpenedCapability> openedCaps = this.hibernateTemplate.loadAll(OpenedCapability.class);
		List<CapabilityInfo> allCapabilitys = this.hibernateTemplate.loadAll(CapabilityInfo.class);
		List<FilterRule> filterRules = hibernateTemplate.loadAll(FilterRule.class);
		List<BlacklistRule> blacklistRules = hibernateTemplate.loadAll(BlacklistRule.class);
		// 加载归属地查询配置信息
		List<HomeQueryTagConfig> homeQueryTagConfigs = hibernateTemplate.loadAll(HomeQueryTagConfig.class);

		// 加载tp_hcode表军网号段,add by ZT,2013-06-21
		List tpHcodes99 =  hibernateTemplate.find("from TPHcode t where t.tspId=99");

//		// 加载SGW_PROV_TRAFFIC_LMT_CFG
//		List<ProvTrafficLmtCfg> provTrafficLmtCfgList = hibernateTemplate.find("from ProvTrafficLmtCfg");
//		// 加载SGW_CAPABILITY_ABN_LMT_CFG
//		List<CapabilityAbnLmtCfg> capabilityAbnLmtCfgList = hibernateTemplate.find("from CapabilityAbnLmtCfg");
//		// 加载SGW_CAPABILITY_ABN_RC_CFG
//		List<CapabilityAbnRcCfg> capabilityAbnRcCfgList = hibernateTemplate.find("from CapabilityAbnRcCfg");
//		// 加载T_FLUX_CTRL_BY_KEY_RULE
//		List<FluxCtrlByKeyRule> fluxCtrlByKeyRuleList = hibernateTemplate.find("from FluxCtrlByKeyRule");

		// 加载能力生命周期配置
//		ConcurrentHashMap<String, CapabilityLifeBean> capabilityLifeCfgMap = sgwViewDao.getCapabilityLifeCfg();
//		confSrv.setCapabilityLifeCfgMap(capabilityLifeCfgMap);
//		// 加载能力流控配置
//		ConcurrentHashMap<String, CapabilityLimitCfgBean> capabilityLimitCfgMap = sgwViewDao.getCapabilityLimitCfg();
//		confSrv.setCapabilityLimitCfgMap(capabilityLimitCfgMap);
//		// 加载新的黑名单配置
//		ConcurrentHashMap<String, BlacklistRuleView> blackRuleCfgMap = sgwViewDao.getBlackRuleCfg();
//		confSrv.setBlackRuleCfgMap(blackRuleCfgMap);
//		// 加载黑名单结果列表
//		ConcurrentHashMap<String, BlackListResult> blackListResultMap = new ConcurrentHashMap<String, BlackListResult>();
//		List<BlackListResult> blackListResultList = sgwViewDao.getBlackListResultList();
//		for (BlackListResult blackResult : blackListResultList) {
//			blackListResultMap.put(blackResult.getKey(), blackResult);
//		}
//		confSrv.setBlackListResultMap(blackListResultMap);
//		// 加载敏感字段配置
//		ConcurrentHashMap<String, SensitivtyCfg> sensitivtyCfgMap = this.sgwViewDao.getSensitivtyCfg();
//		confSrv.setSensitivtyCfgMap(sensitivtyCfgMap);

		Map<Integer, SGWChannel> newChannelMap = new HashMap<Integer, SGWChannel>();
		SGWChannel oldChannel = null;
		for (SGWChannel channel : sgwChannels) {
			oldChannel = confSrv.getSgwChannelMap().get(channel.getId());
			if (oldChannel != null) {
				oldChannel.setChannelHost(channel.getChannelHost());
				oldChannel.setUri(channel.getUri());
				oldChannel.setIsStart(channel.getIsStart());
				oldChannel.setMaxRecvQueueSize(channel.getMaxRecvQueueSize());
			} else {
				oldChannel = channel;
				oldChannel.setStatus(NodeStatus.OFF_LINE);
				confSrv.updateChannelStatus2DB(oldChannel.getId(), NodeStatus.OFF_LINE);
			}
			newChannelMap.put(oldChannel.getId(), oldChannel);
		}
		confSrv.setSgwChannelMap(newChannelMap, true);

		// 转换为MAP,Key 是id

		ConcurrentHashMap<Integer, Node> newNodeMap = new ConcurrentHashMap<Integer, Node>();
		ConcurrentHashMap<String, Node> newName2NodeMap = new ConcurrentHashMap<String, Node>();

		Node oldNode = null;
		for (Node node : nodes) {
			oldNode = ConfigService.id2NodeMap.get(node.getId());
			if (oldNode != null) {
				oldNode.setHostId(node.getHostId());
				oldNode.setNodeCode(node.getNodeCode());
				oldNode.setNodeName(node.getNodeName());
				oldNode.setNodeDesc(node.getNodeDesc());
				oldNode.setChannelId(node.getChannelId());
				oldNode.setCheckType(node.getCheckType());
				oldNode.setUri(node.getUri());
				oldNode.setConnectType(node.getConnectType());
				oldNode.setPassword(node.getPassword());
				oldNode.setServerUrl(node.getServerUrl());
				oldNode.setWideNodeId(node.getWideNodeId());
				oldNode.setNeedActive(node.getNeedActive());
				oldNode.setMaxSendQueueSize(node.getMaxSendQueueSize());

				if (node.getNodeType() == NodeType.NODE_WS_NE && node.getStatus() == NodeStatus.OFF_LINE) {
					oldNode.setStatus(NodeStatus.ON_LINE);
					confSrv.updateNodeStatus2DB(oldNode.getId(), oldNode.getStatus());
				}

			} else {
				oldNode = node;
				if (oldNode.getNodeType() == NodeType.NODE_WS_NE) {
					oldNode.setStatus(NodeStatus.ON_LINE);
				} else {
					oldNode.setStatus(NodeStatus.OFF_LINE);
				}
				confSrv.updateNodeStatus2DB(oldNode.getId(), oldNode.getStatus());
			}
			newNodeMap.put(oldNode.getId(), oldNode);
			newName2NodeMap.put(oldNode.getHostId(), oldNode);
		}
		confSrv.setId2NodeMap(newNodeMap, true);
		confSrv.setName2NodeMap(newName2NodeMap);

		ConcurrentHashMap<String, SGWCapabilityProvided> newCapabiltyProvidedMap = new ConcurrentHashMap<String, SGWCapabilityProvided>();
		SGWCapabilityProvided oldProvid = null;
		for (SGWCapabilityProvided capa : capaProvided) {
			oldProvid = newCapabiltyProvidedMap.get(capa.getPeerNodeId() + capa.getServiceContextID());
			if (oldProvid != null) {
				oldProvid.setPriority(capa.getPriority());
				oldProvid.setWeight(capa.getWeight());
				oldProvid.setServiceTitle(capa.getServiceTitle());
			} else {
				oldProvid = capa;
				oldProvid.setStatus(NodeStatus.OFF_LINE);
			}
			newCapabiltyProvidedMap.put(capa.getPeerNodeId() + capa.getServiceContextID(), oldProvid);
		}
		confSrv.setCapabiltyProvidedMap(newCapabiltyProvidedMap);
		confSrv.setCapabilityProvidedList(newCapabiltyProvidedMap.values(), true);

		Map filterRuleMap = new HashMap();
		Object ruleMap = null;
		for (FilterRule fr : filterRules) {
			ruleMap = (Map) filterRuleMap.get(fr.getCapability());
			if (ruleMap == null) {
				ruleMap = new HashMap();
				filterRuleMap.put(fr.getCapability(), ruleMap);
			}
			((Map) ruleMap).put(fr.getXmlTag(), fr.getRule());
		}

		Map ctrlMap = new HashMap();
		CapabilityCtrlBean cbean = null;
		for (CapabilityInfo cap : allCapabilitys) {
			cbean = new CapabilityCtrlBean();
			cbean.setCapability(cap.getCapability());
			cbean.setFlowid(cap.getFlowID());
			cbean.setPriority(cap.getPriority());
			cbean.setNumIdiographType(cap.getNumIdiographType());
			cbean.setTimeoutWarning(cap.getTimeoutWarning());
			cbean.setTimeoutDropMsg(cap.getTimeoutDropMsg());
			cbean.setControlType(0);
			cbean.setIfKeyStat(cap.isIfKeyStat());
			cbean.setKeyTagSet(cap.getKeyTagsSet());
			cbean.setFilterMap((Map) filterRuleMap.get(cap.getCapability()));
			cbean.setMaxReqSize(cap.getMaxReqSize());
			ctrlMap.put(cap.getCapability(), cbean);
		}
		for (OpenedCapability op : openedCaps) {
			cbean = new CapabilityCtrlBean();
			Node node = newNodeMap.get(op.getNodeId());
			if (node == null) {
				logger.warn("can't find node of id " + op.getNodeId() + " for opened capability:" + op.getCapability() + " id :" + op.getId());
				continue;
			}
			ctrlMap.put(op.getCapability() + node.getHostId(), cbean);
			cbean.setCapability(op.getCapability());
			cbean.setPriority(op.getPriority());
			cbean.setTimeoutDropMsg(op.getTimeoutDropMsg());
			cbean.setFcontrolCycle(op.getFcontrolCycle());
			// cbean.setFcontrolReconInterval(op.getFcontrolReconInterval());
			cbean.setCountWarning(op.getCountWarning());
			cbean.setCountDisconnect(op.getCountDisconnect());
			cbean.setFluxWarning(op.getFluxWarning());
			cbean.setFluxDisconnect(op.getFluxDisconnect());
			cbean.setControlType(op.getControlType());
		}
		confSrv.setCapabilityCtrlMap(ctrlMap, true);

		// 加载归属地查询配置信息
		Map<String, HomeQueryTagConfig> hqtConfMap = new HashMap<String, HomeQueryTagConfig>();
		for (HomeQueryTagConfig c : homeQueryTagConfigs) {
			hqtConfMap.put(c.getCapability(), c);
		}
		confSrv.setHomeQueryTagConfigMap(hqtConfMap, true);

		HashMap<String, BlacklistRule> blacklistRuleMap = new HashMap<String, BlacklistRule>();
		for (BlacklistRule rule : blacklistRules) {
			rule.setKeyAvpPath(DccAvpHelper.convertXPath2AvpPath(rule.getKeyXmlTag()));
			rule.setRcAvpPath(DccAvpHelper.convertXPath2AvpPath(rule.getRcXmlTag()));
			blacklistRuleMap.put(rule.getCapability(), rule);
		}
		confSrv.setBlacklistRuleMap(blacklistRuleMap);

		ConcurrentHashMap<String, TPHcode> tpHcodes99Map = new ConcurrentHashMap<String, TPHcode>();
		if (tpHcodes99 != null && tpHcodes99.size() > 0) {
			for (Object tpHcode : tpHcodes99) {
				tpHcodes99Map.put("" + ((TPHcode)tpHcode).getHcodeId(), (TPHcode)tpHcode);
			}
		}
		confSrv.setTPHcodes99(tpHcodes99Map);

		/*
		 * ConcurrentHashMap<String, ProvTrafficLmtCfg> provTrafficLmtCfgMap =
		 * new ConcurrentHashMap<String, ProvTrafficLmtCfg>(); if
		 * (provTrafficLmtCfgList != null && provTrafficLmtCfgList.size() > 0) {
		 * for (ProvTrafficLmtCfg provTrafficLmtCfg : provTrafficLmtCfgList) {
		 * provTrafficLmtCfgMap.put(provTrafficLmtCfg.getProvId(),
		 * provTrafficLmtCfg); } }
		 * confSrv.setProvTrafficLmtCfgMap(provTrafficLmtCfgMap);
		 */

//		// 网元+省限流
//		confSrv.setProvTrafficLmtCfgMap(confSrv.list2FluxCtrlByNodeRuleMap(provTrafficLmtCfgList));
//
//		// 转售商限流
//		confSrv.setFluxCtrlByKeyRuleMap(confSrv.list2FluxCtrlByKeyRuleMap(fluxCtrlByKeyRuleList));
//
//		ConcurrentHashMap<String, CapabilityAbnLmtCfg> capabilityAbnLmtCfgMap = new ConcurrentHashMap<String, CapabilityAbnLmtCfg>();
//		if (capabilityAbnLmtCfgList != null && capabilityAbnLmtCfgList.size() > 0) {
//			for (CapabilityAbnLmtCfg capabilityAbnLmtCfg : capabilityAbnLmtCfgList) {
//				capabilityAbnLmtCfgMap.put(capabilityAbnLmtCfg.getCapability(), capabilityAbnLmtCfg);
//			}
//		}
//
//		if (capabilityAbnRcCfgList != null && capabilityAbnRcCfgList.size() > 0) {
//			for (CapabilityAbnRcCfg capabilityAbnRcCfg : capabilityAbnRcCfgList) {
//				String capability = capabilityAbnRcCfg.getCapability();
//				String resultValue = capabilityAbnRcCfg.getResultValue();
//				CapabilityAbnLmtCfg capabilityAbnLmtCfg = capabilityAbnLmtCfgMap.get(capability);
//				if (capability.equalsIgnoreCase("ALL")) {
//					if (capabilityAbnLmtCfg == null) {
//						capabilityAbnLmtCfg = new CapabilityAbnLmtCfg();
//						capabilityAbnLmtCfgMap.put("ALL", capabilityAbnLmtCfg);
//					}
//				}
//				if (capabilityAbnLmtCfg != null) {
//					int error = resultValue.equals("*") ? -1 : Integer.parseInt(resultValue);
//					if (capabilityAbnRcCfg.getResultColumn().trim().toLowerCase().equals("result_code")) {
//						capabilityAbnLmtCfg.putResultCode(error);
//					} else if (capabilityAbnRcCfg.getResultColumn().trim().toLowerCase().equals("service_result_code")) {
//						capabilityAbnLmtCfg.putServiceResultCode(error);
//					} else if (capabilityAbnRcCfg.getResultColumn().trim().toLowerCase().equals("rc")) {
//						capabilityAbnLmtCfg.putRc(error);
//					}
//				}
//			}
//		}
//		confSrv.setCapabilityAbnLmtCfgMap(capabilityAbnLmtCfgMap);

	}

	/**
	 * @param curConfig
	 * @param nodeID
	 * @return
	 */
	private void loadConvMapInfoTable(Configuration curConfig) {
		List<ConvMapInfo> convMapInfos = hibernateTemplate.loadAll(ConvMapInfo.class);
		if (!convMapInfos.isEmpty()) {
			String confVal = new Gson().toJson(convMapInfos);
			curConfig.addProperty("SWGChannel.Xml2AvpMappings", confVal);
		}
	}

	@Autowired
	@Qualifier("sessionFactory")
	public void setSessionFact(SessionFactory sessionFact) {
		this.hibernateTemplate = new HibernateTemplate(sessionFact);
	}

	public List<Node> loadNode() {
		return this.hibernateTemplate.loadAll(Node.class);
	}

	public List<SGWChannel> loadSGWChannel() {
		return this.hibernateTemplate.loadAll(SGWChannel.class);
	}

	public List<SGWCapabilityProvided> loadSGWCapability() {
		return this.hibernateTemplate.loadAll(SGWCapabilityProvided.class);
	}
}